return function(BOXUI)

local utils = BOXUI.utils
local int = utils.int
local clamp = utils.clamp

local M = utils.newclass("slider")

-- AREAS
local units = {}
M.units = units

units.SLIDER_INC = utils.newbox("inc" ) -- name = str
units.SLIDER_DEC = utils.newbox("dec")
units.SLIDER_NOB = utils.newbox("nob")

local incdec = function(owner, dir)
	local value = utils.clamp(owner.value + dir * owner.step, owner.valueMin, owner.valueMax)
	if value == owner.value then return end
	owner.value = value
	local ratio = owner.value / (owner.valueMax - owner.valueMin)

	local boxes = owner.boxes
	local nob = boxes.nob

	if owner.vertical then
		local bh = boxes.dec.height
		local nobpos = boxes.dec.y - nob.height - int((owner.height - 2 * bh - nob.height) * ratio)
		boxes.nob.y = nobpos
	else
		local bw = boxes.dec.width
		local nobpos = bw + int((owner.width - 2 * bw - nob.width) * ratio)
		boxes.nob.x = nobpos
	end
end

units.SLIDER_INC.click = function(owner) incdec(owner,  1) end
units.SLIDER_DEC.click = function(owner) incdec(owner, -1) end


M.init = function(self, x, y, width, height)
	self.theme = BOXUI.theme
	self.x, self.y = x, y
	self.width, self.height = width, height
	
	self.value = 75
	self.valueMin = 0
	self.valueMax = 100
	self.step = 1
	self.stepTime = 0.010
	self.stepInit = 0.250
	self.dt = 0
	self.active = nil
	self.selected = nil
	self.onClick = nil
	self.font = love.graphics.getFont()

	self.units = utils.deepcopy(M.units)
end

M.adjust = incdec

M.refresh = function(self)
	local theme = self.theme
	local width, height = self.width, self.height
	local bw, bh = theme.sliderButtonWidth, theme.sliderButtonHeight
	local nt, nl = theme.sliderNobThickness, theme.sliderNobLength
	local u = self.units
	local boxes = {}
	local ratio = self.value / (self.valueMax - self.valueMin)
	--self.stepTime = (self.step) / (self.valueMax - self.valueMin)
	self.boxes = boxes
	if self.vertical then
		local bx = int((width - bw) / 2)
		local nobx = int((width - nl) / 2)
		local nobpos = height - bh - nt - int((height - 2 * bh - nt) * ratio)
		boxes.inc = utils.setbox(u.SLIDER_INC, bx, 0, bw, bh)
		boxes.dec = utils.setbox(u.SLIDER_DEC, bx, height - bh, bw, bh)
		boxes.nob = utils.setbox(u.SLIDER_NOB, nobx, nobpos, nl, nt)
	else
		local by = int((height - bh) / 2)
		local noby = int((height - nl) / 2)
		local nobpos = bw + int((width - 2 * bw - nt) * ratio)
		boxes.dec = utils.setbox(u.SLIDER_DEC, 0, by, bw, bh)
		boxes.inc = utils.setbox(u.SLIDER_INC, width - bw, by, bw, bh)
		boxes.nob = utils.setbox(u.SLIDER_NOB, nobpos, noby, nt, nl)
	end
	
	self.draw = self.theme.draw.slider
end



M.wheelmoved = function(self, x, y, dx, dy)

end

M.mousemoved  = function(self, x, y, button)
	x, y = x - self.x, y - self.y
	self.active = nil
	for k,v in pairs(self.boxes) do
		if utils.includesPoint(v, x, y) then self.active = v break end
	end
end

M.mousepressed  = function(self, x, y, button)
	x, y = x - self.x, y - self.y
	self.dt = 0
	self.stepping = false
	self.selected = button == 1 and self.active
end

M.mousereleased  = function(self, x, y, button)
	local active, selected = self.active, self.selected
	if active and active == selected and active.click then
		active.click(self)
	end
	self.selected = false
end

M.update = function(self, dt)
	local active, selected = self.active, self.selected
	if not selected or selected ~= active or not selected.click then return end
	
	self.dt = self.dt + dt
	if not self.stepping then
		if self.dt < self.stepInit then return end
		self.stepping = true; self.dt = self.dt - self.stepInit
	end
	if self.dt < self.stepTime then return end
	active.click(self)
	self.dt = self.dt - self.stepTime
end

--M.focus = function(self) self.active = true end
--M.unfocus = function(self) self.active = false end

BOXUI.add(M)
end

